package com.luoye.unionlotto;

import java.util.*;

public abstract class UnionlottoAnalyzer {
    protected List<Unionlotto> unionlottoList;
    //protected UnionlottoStatistic unionlottoStatistic;

    public UnionlottoAnalyzer() {
        this.unionlottoList=new ArrayList<Unionlotto>();
        //this.unionlottoStatistic=new UnionlottoStatistic();
    }

    public abstract void analyze();

    public UnionlottoStatistic doStatistic(List<Unionlotto> unionlottoListParam){
        UnionlottoStatistic unionlottoStatistic=new UnionlottoStatistic();
        //统计
        for(Unionlotto unionlotto:unionlottoListParam){
            for(String redBall:unionlotto.getRedBalls()){
                Integer redCount=unionlottoStatistic.getRedBallCount().get(redBall);
                if(redCount==null){
                    unionlottoStatistic.getRedBallCount().put(redBall,1);
                }else{
                    redCount=redCount.intValue()+1;
                    unionlottoStatistic.getRedBallCount().put(redBall,redCount);
                }
            }
            Integer blueCount=unionlottoStatistic.getBlueBallCount().get(unionlotto.getBlueBall());
            if(blueCount==null){
                blueCount=0;
            }
            blueCount=blueCount.intValue()+1;
            unionlottoStatistic.getBlueBallCount().put(unionlotto.getBlueBall(),blueCount);
        }
        System.out.println(unionlottoStatistic);
        System.out.println(unionlottoStatistic.getRedBallCount());
        System.out.println(unionlottoStatistic.getBlueBallCount());
        //补齐数据
        for(int i=1;i<=33;i++){
            String r=String.format("%02d",i);
            Integer rc=unionlottoStatistic.getRedBallCount().get(r);
            if(rc==null){
                unionlottoStatistic.getRedBallCount().put(r,0);
            }
        }
        for(int i=1;i<=16;i++){
            String b=String.format("%02d",i);
            Integer bc=unionlottoStatistic.getBlueBallCount().get(b);
            if(bc==null){
                unionlottoStatistic.getBlueBallCount().put(b,0);
            }
        }
        System.out.println(unionlottoStatistic.getRedBallCount());
        System.out.println(unionlottoStatistic.getBlueBallCount());
        return unionlottoStatistic;
    }

    public List<Unionlotto> doReduce(UnionlottoStatistic unionlottoStatistic){
        //红球按数量从小到大排序
        Set<String> redBallKeys=unionlottoStatistic.getRedBallCount().keySet();
        String []redBallKeya=redBallKeys.toArray(new String[0]);
        int size=redBallKeya.length;
        for(int i=0;i<size;i++){
            for(int j=0;j<size-i-1;j++){
                int count1=unionlottoStatistic.getRedBallCount().get(redBallKeya[j]);
                int count2=unionlottoStatistic.getRedBallCount().get(redBallKeya[j+1]);
                if(count1>count2){//交换
                    String temp=redBallKeya[j];
                    redBallKeya[j]=redBallKeya[j+1];
                    redBallKeya[j+1]=temp;
                }
            }
        }
        Map<String,Integer> redBallCount=new LinkedHashMap<String, Integer>();
        for (String s : redBallKeya) {
            redBallCount.put(s,unionlottoStatistic.getRedBallCount().get(s));
        }
        //System.out.println(redBallCount);
        unionlottoStatistic.setRedBallCount(redBallCount);
        System.out.println(unionlottoStatistic.getRedBallCount());
        //红球概率最高的一组和概率最低的一组
        String maxRedBalls[]=new String[6];
        for(int i=0;i<6;i++){
            maxRedBalls[i]=redBallKeya[size-i-1];
        }
        String minRedBalls[]=new String[6];
        for(int i=0;i<6;i++){
            minRedBalls[i]=redBallKeya[i];
        }


        //蓝球概率最高的一组和概率最低的一组
        String maxBlueBall="01";
        String minBlueBall="01";
        Set<String> blueBallKeys=unionlottoStatistic.getBlueBallCount().keySet();
        for(String blueBall:blueBallKeys) {
            if("01".equals(blueBall)){
                continue;
            }
            int count = unionlottoStatistic.getBlueBallCount().get(blueBall);
            int count1=unionlottoStatistic.getBlueBallCount().get(maxBlueBall);
            if(count>count1){
                maxBlueBall=blueBall;
            }
            int count2=unionlottoStatistic.getBlueBallCount().get(minBlueBall);
            if(count<count2){
                minBlueBall=blueBall;
            }
        }

        System.out.println("");
        System.out.println("");
        System.out.print("最大一组：");
        for(String redBall:maxRedBalls){
            System.out.print(redBall+" ");
        }
        System.out.println("- "+maxBlueBall);
        System.out.print("最小一组：");
        for(String redBall:minRedBalls){
            System.out.print(redBall+" ");
        }
        System.out.println("- "+minBlueBall);

        List<Unionlotto> result=new ArrayList<Unionlotto>();
        result.add(new Unionlotto("最大一组",Arrays.asList(maxRedBalls),maxBlueBall));
        result.add(new Unionlotto("最小一组",Arrays.asList(minRedBalls),minBlueBall));
        return result;
    }

    public void printResult(List<Unionlotto> result){
        //输出结果
        for(Unionlotto unionlotto:result){
            System.out.print(unionlotto.getDate()+":");
            for(String redBall:unionlotto.getRedBalls()){
                System.out.print(redBall+" ");
            }
            System.out.println("- "+unionlotto.getBlueBall());
        }
    }

    //全量最大最小值方法
    public List<Unionlotto> fullMaxAndMin(){
        List<Unionlotto> result=this.doReduce(this.doStatistic(this.unionlottoList));
        //printResult(result);
        return result;
    }

    //随机取组最大最小值方法
    public List<Unionlotto> randMaxAndMin(){
        int rand= (int) (Math.random()*10+1);
        System.out.println(rand);

        List<Unionlotto> unionlottos=new ArrayList<Unionlotto>();
        int size=this.unionlottoList.size();
        for(int i=0;i<size;i++){
            if(i%rand==0){
                unionlottos.add(this.unionlottoList.get(i));
            }
        }

        List<Unionlotto> result=this.doReduce(this.doStatistic(unionlottos));
        if(result!=null&result.size()>0){
            result.get(0).setDate("随机最大");
        }
        if(result!=null&result.size()>1){
            result.get(1).setDate("随机最小");
        }
        //printResult(result);
        return result;
    }

    //挨个求和法
    public List<Unionlotto> sumOneByOne(){
        List<Unionlotto> result=new ArrayList<Unionlotto>();

        int redBallSums[]=new int[6];
        int blueBallSum=0;
        for(Unionlotto unionlotto:this.unionlottoList){
            int blueBall=Integer.parseInt(unionlotto.getBlueBall());
            blueBallSum+=blueBall;
            for(int i=0;i<6;i++){
                redBallSums[i]+=Integer.parseInt(unionlotto.getRedBalls().get(i));
            }
        }
        //求余
        int rand= (int) (Math.random()*16+1);
        int blueBall=(blueBallSum+rand)%16+1;
        System.out.println(rand+":b:"+blueBall);
        Set<Integer> redBalls=new HashSet<Integer>();
        for(int i=0;redBalls.size()<6;i++){
            rand= (int) (Math.random()*33+1);
            int redBall=(redBallSums[i%6]+rand)%33+1;
            System.out.println(rand+":r:"+redBall);
            redBalls.add(redBall);
        }

        List<String> redBallList=new ArrayList<String>();
        for(int redBall:redBalls){
            redBallList.add(String.format("%02d",redBall));
        }
        Unionlotto unionlotto=new Unionlotto("求和算法",redBallList,String.format("%02d",blueBall));
        result.add(unionlotto);

        return result;
    }

    //随机算法
    public List<Unionlotto> randOne(){
        List<Unionlotto> result=new ArrayList<Unionlotto>();

        int blueBall=(int) (Math.random()*16+1);
        System.out.println("b:"+blueBall);
        Set<Integer> redBalls=new HashSet<Integer>();
        for(int i=0;redBalls.size()<6;i++){
            int redBall=(int) (Math.random()*33+1);
            System.out.println(":r:"+redBall);
            redBalls.add(redBall);
        }

        List<String> redBallList=new ArrayList<String>();
        for(int redBall:redBalls){
            redBallList.add(String.format("%02d",redBall));
        }
        Unionlotto unionlotto=new Unionlotto("随机一组",redBallList,String.format("%02d",blueBall));
        result.add(unionlotto);

        return result;
    }

    //补缺算法
    public List<Unionlotto> fillVacancy(List<Unionlotto> baseList){
        List<Unionlotto> result=new ArrayList<Unionlotto>();
        Set<String> redBalls=new HashSet<>();
        Set<String> blueBalls=new HashSet<>();
        for(Unionlotto unionlotto:baseList){
            for(String redBall:unionlotto.redBalls){
                redBalls.add(redBall);
            }
            blueBalls.add(unionlotto.blueBall);
        }
        List<String> remainRedBalls=new ArrayList<>();
        for(int i=1;i<=33;i++){
            String ball=String.format("%02d",i);
            if(!redBalls.contains(ball)){
                remainRedBalls.add(ball);
            }
        }
        List<String> remainBlueBalls=new ArrayList<>();
        for(int i=1;i<=16;i++){
            String ball=String.format("%02d",i);
            if(!blueBalls.contains(ball)){
                remainBlueBalls.add(ball);
            }
        }
        System.out.println("remainRedBalls->"+remainRedBalls);
        System.out.println("remainBlueBalls->"+remainBlueBalls);

        Set<String> selectRedBalls=new HashSet<>();
        int rrbs=remainRedBalls.size();
        if(rrbs<=6){
            for(String redBall:remainRedBalls){
                selectRedBalls.add(redBall);
            }
            for(int i=0;selectRedBalls.size()<6;i++){
                int redBall=(int) (Math.random()*33+1);
                System.out.println(":r:"+redBall);
                String redBallStr=String.format("%02d",redBall);
                selectRedBalls.add(redBallStr);
            }
        }else {
            for (int i = 0; selectRedBalls.size() < 6; i++) {
                int redBallIndex = (int) (Math.random() * rrbs);
                String redBall = remainRedBalls.get(redBallIndex);
                System.out.println("fillVacancy:r:" + redBall);
                selectRedBalls.add(redBall);
            }
        }
        String selectBlueBall="";
        int rbbs=remainBlueBalls.size();
        if(rbbs<=0){
            int blueBall=(int) (Math.random()*16+1);
            selectBlueBall=String.format("%02d",blueBall);
        }else {
            int bbi = (int) (Math.random() * rbbs);
            selectBlueBall = remainBlueBalls.get(bbi);
        }
        List<String> redBallList=new ArrayList<String>();
        for(String redBall:selectRedBalls){
            redBallList.add(redBall);
        }
        Unionlotto unionlotto=new Unionlotto("补缺一组",redBallList,selectBlueBall);
        result.add(unionlotto);

        return result;
    }

}
